#ifndef __YUECHUAN_FD_MANAGER_H
#define __YUECHUAN_FD_MANAGER_H

#include<memory>
#include<sys/stat.h>
#include"thread.h"
#include"iomanager.h"
#include"singleton.h"

namespace yuechuan {
    /**
     * @brief 文件句柄类
     */
    class FdCtx : public std::enable_shared_from_this<FdCtx> {
    public:
        typedef std::shared_ptr<FdCtx> ptr;
        /**
         * @brief 含参构造函数
         * @details 默认的创建文件句柄对象，不是系统、用户非阻塞，非socket文件，发送超时时间和接收超时时间都为-1
         * @param fd 文件句柄
         *
         */
        FdCtx(int fd);

        /**
         * @brief 析构函数
         */
        ~FdCtx();

        /**
         * @brief 初始化函数
         * @details 判断文件句柄是否是socket，是否是系统级非阻塞，或用户级非阻塞
         * @return bool ,m_isInit的值
         */
        bool init();

        /**
         * @brief 是否已经初始化
         * @return bool m_isInit
         */
        bool isInit() const { return m_isInit; }

        /**
         * @brief 是否是socket文件句柄
         * @return bool m_isSocket
         */
        bool isSocket() const { return m_isSocket; }

        /**
         * @brief 是否被关闭
         * @return bool m_isClose
         */
        bool isClose() const { return m_isClose; }


        /**
         * @brief 设置用户级非阻塞
         * @param v 非阻塞状态
         */
        void setUserNonblock(bool v) { m_userNonblock = v; }

        /**
         * @brief 是否是用户级非阻塞
         * @return bool m_userNonblock
         */
        bool getUserNonblock() const { return m_userNonblock; }

        /**
         * @brief 设置系统级非阻塞
         * @param v 非阻塞状态
         */
        void setSysNonblock(bool v) { m_sysNonblock = v; }

        /**
         * @brief 是否是系统级非阻塞
         * @return bool m_sysNonblock
         */
        bool getSysNonblock() const { return m_sysNonblock; }

        /**
         * @brief 设置超时时间
         * @param type 是socket中内置的宏定义 SO_RECTIMEO 和SO_SNDTIMEO两个值中的一个
         * @param v 超时时间
         */
        void setTimeout(int type, uint64_t v);

        /**
         * @brief 获取超时时间
         * @param type 是socket中内置的宏定义 SO_RECTIMEO 和SO_SNDTIMEO两个值中的一个
         * @return uint64_t 超时时间以ms为单位
         */
        uint64_t getTimeout(int type);

    private:
        /// 是否初始化
        bool m_isInit: 1;
        /// 是否是socket
        bool m_isSocket: 1;
        /// 是不是系统态为非阻塞
        bool m_sysNonblock: 1;
        /// 是否用户态非阻塞
        bool m_userNonblock: 1;
        /// 是否关闭
        bool m_isClose: 1;
        /// 文件句柄id
        int m_fd;

        /// 接收超时时间
        uint64_t m_recvTimeout;
        /// 发送超时时间
        uint64_t m_sendTimeout;

        /// 句柄和IO相关要绑定一个IO管理类
        IOManager *m_ioManager;
    };

    /**
     * @brief 句柄的管理类
     */
    class FdManager {
    public:
        typedef RWMutex RWMutexType;

        /**
         * @brief 无参构造函数
         * @details 初始化句柄列表的大小为64
         */
        FdManager();

        /**
         * @brief 析构函数
         */
        ~FdManager();

        /**
         * @brief 获取文件句柄号对应的文件句柄类对象
         * @param fd 文件句柄号
         * @param auto_create 当没有该句柄时，是否自动创建一个
         * @return FdCtx::ptr 句柄列表中的一个类对象指针，或者新创建的类对象指针
         */
        FdCtx::ptr get(int fd, bool auto_create = false);

        /**
         * @brief 从句柄列表中删除一个句柄对象
         * @param fd 要删除的句柄对象的m_fd值
         */
        void del(int fd);

    private:
        RWMutexType m_mutex;
        std::vector<FdCtx::ptr> m_datas;

    };

    typedef Singleton<FdManager> FdMgr;
} // namespace yuechuan


#endif // __YUECHUAN_FD_MANAGER_H